﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text;
using YunSpace.Application.Infrastructure;
using YunSpace.Application.SystemManage;
using YunSpace.Core;
using YunSpace.Core.Image;
using YunSpace.Domain.IRepository.SiteLibraryManage;
using YunSpace.Domain.IRepository.SystemManage;
using YunSpace.Domain.ViewModel.SiteMgr.Pdf;
using YunSpace.Repository.SiteLibraryManage;

namespace YunSpace.Application.SiteMgr
{
    public class PdfApp
    {
        private readonly ISiteRepository _siteRepository = new SiteRepository();
        private readonly ItemsDetailApp _itemsDetailApp = new ItemsDetailApp();
        private static readonly string _imageRawDirectory = AppDomain.CurrentDomain.BaseDirectory;

        private const string SitePhotoableType = "Site";
        private const string SpacePhotoableType = "Space";
        private const string ActivitiesCasePhotoableType = "ActivitiesCase";
        private const string SpacePlaneFilePhotoableType = "SpacePlaneFile";

        /// <summary>
        /// 创建场地模板
        /// </summary>
        /// <param name="toSaveFileName">待保存的文件名</param>
        /// <param name="imgPrefix">图片路径前缀</param>
        /// <param name="siteId"></param>
        public void CreateSitePdf(string toSaveFileName, string imgPrefix, string siteId)
        {
            var sitePdfDto = _siteRepository.GetSitePdfDto(siteId);

            if (sitePdfDto == null)
            {
                throw new Exception("没有该场地的信息");
            }

            var siteName = sitePdfDto.SiteName;

            //创建目录
            CreateImageDirectoriesIfNotExist(_imageRawDirectory, siteName);

            //场地信息处理
            var sitePhotoDtos = _siteRepository.GetPhotoPdfDtos(siteId, SitePhotoableType);
            //所有水印图片
            var allWaterMarkImgs = new List<KeyValuePair<string, string>>();
            var waterMarkImgs = GenerateWaterMarkImgs(siteName, SitePhotoableType, sitePhotoDtos);

            allWaterMarkImgs.AddRange(waterMarkImgs);

            var pdfTemplate = new PdfYSTemplate(toSaveFileName, imgPrefix);
            var spaceForPage2Imgs = waterMarkImgs.Take(3).ToList();
            //已使用的水印图片
            var usedWaterMarkImgFileNames = new List<KeyValuePair<string, string>>();

            usedWaterMarkImgFileNames.AddRange(spaceForPage2Imgs);

            if (spaceForPage2Imgs.Count > 1)
            {
                var spaceMarkAttrPdfDtos = _siteRepository.GetSpaceMarketAttrPdfDtos(siteId);
                pdfTemplate.CreatePageFor2(sitePdfDto, spaceForPage2Imgs.Select(x => x.Key).ToList(), spaceMarkAttrPdfDtos);
            }

            //空间信息处理
            var spacePdfDtos = _siteRepository.GetSpacePdfDtos(siteId);
            var facilities = ResolveFacilities(sitePdfDto.Facilities);

            if (spacePdfDtos != null && spacePdfDtos.Any())
            {
                foreach (var spacePdfDto in spacePdfDtos)
                {
                    var spacePhotoDtos = _siteRepository.GetPhotoPdfDtos(spacePdfDto.Id, SpacePhotoableType);
                    var waterMarkSpaceImgs = GenerateWaterMarkImgs(siteName, SpacePhotoableType, spacePhotoDtos);

                    allWaterMarkImgs.AddRange(waterMarkSpaceImgs);

                    pdfTemplate.AddNewPage();

                    if (waterMarkSpaceImgs.Any())
                    {

                        pdfTemplate.CreatePageFor3(sitePdfDto.SiteName, waterMarkSpaceImgs[0].Key, spacePdfDto, facilities);
                        usedWaterMarkImgFileNames.Add(waterMarkSpaceImgs[0]);

                        if (waterMarkSpaceImgs.Count > 1)
                        {
                            pdfTemplate.AddNewPage();

                            var spacePlanePhotoDtos = _siteRepository.GetPhotoPdfDtos(spacePdfDto.Id, SpacePlaneFilePhotoableType);
                            string planeImg = null;

                            if (spacePlanePhotoDtos != null && spacePlanePhotoDtos.Any() && !spacePlanePhotoDtos[0].Path.IsNullOrEmpty())
                            {
                                planeImg = GenerateWaterMarkImgs(siteName, SpacePhotoableType, spacePhotoDtos)[0].Key;
                            }

                            pdfTemplate.CreatePageFor4(sitePdfDto.SiteName, waterMarkSpaceImgs[1].Key, spacePdfDto.SpaceName, planeImg);
                            usedWaterMarkImgFileNames.Add(waterMarkSpaceImgs[1]);
                        }
                    }

                    //活动信息处理
                    var activitiyCaseDtos = _siteRepository.GetActivitiesCasePdfDtos(siteId, spacePdfDto.Id);

                    if (activitiyCaseDtos != null && activitiyCaseDtos.Any())
                    {
                        foreach (var activitiesCasePdfDto in activitiyCaseDtos)
                        {
                            var activitiesCasePhotoDtos = _siteRepository.GetPhotoPdfDtos(activitiesCasePdfDto.Id, ActivitiesCasePhotoableType);
                            var waterMarkActivitiesCaseImgNames = GenerateWaterMarkImgs(siteName, ActivitiesCasePhotoableType, activitiesCasePhotoDtos);
                            allWaterMarkImgs.AddRange(waterMarkActivitiesCaseImgNames);

                            var page5UsedImgs = waterMarkActivitiesCaseImgNames.Take(3).ToList();

                            pdfTemplate.AddNewPage();
                            pdfTemplate.CreatePageFor5(siteName, activitiesCasePdfDto, page5UsedImgs.Select(x => x.Key).ToList());
                            usedWaterMarkImgFileNames.AddRange(page5UsedImgs);
                        }
                    }


                    //剩余照片处理
                    var remnantImgs = allWaterMarkImgs.Except(usedWaterMarkImgFileNames).ToList();

                    if (remnantImgs.Any())
                    {
                        var imgsOfPageFor7 = remnantImgs.Take(6).ToList();

                        if (imgsOfPageFor7.Any())
                        {
                            usedWaterMarkImgFileNames.AddRange(imgsOfPageFor7);

                            pdfTemplate.AddNewPage();
                            pdfTemplate.CreatePageFor7(siteName, imgsOfPageFor7.ToList());
                        }
                    }

                    if (sitePdfDto.Level != "B" || waterMarkSpaceImgs.Count <= 2) continue;

                    var spaceSupplementDto = _siteRepository.GetSpaceSupplementPdfDtos(spacePdfDto.Id);

                    pdfTemplate.AddNewPage();
                    pdfTemplate.CreatePageFor8(siteName, waterMarkSpaceImgs[2].Key, spaceSupplementDto);
                }


            }
            else
            {
                //剩余照片处理
                var remnantImgs = allWaterMarkImgs.Except(usedWaterMarkImgFileNames).ToList();

                if (remnantImgs.Count > 1)
                {
                    var imgsOfPageFor7 = remnantImgs.Take(6).ToList();

                    if (imgsOfPageFor7.Count > 1)
                    {
                        usedWaterMarkImgFileNames.AddRange(imgsOfPageFor7);

                        pdfTemplate.AddNewPage();
                        pdfTemplate.CreatePageFor7(siteName, imgsOfPageFor7.ToList());
                    }
                }
            }

            pdfTemplate.Save();
        }

        /// <summary>
        /// 创建图片目录，如果不存在该目录
        /// </summary>
        /// <param name="prefix"></param>
        /// <param name="siteName"></param>
        private static void CreateImageDirectoriesIfNotExist(string prefix, string siteName)
        {
            Directory.CreateDirectory($@"{prefix}\PDF\{DateTime.Now:yyyyMMdd}\{siteName}\{SitePhotoableType}");
            Directory.CreateDirectory($@"{prefix}\PDF\{DateTime.Now:yyyyMMdd}\{siteName}\{SpacePhotoableType}");
            Directory.CreateDirectory($@"{prefix}\PDF\{DateTime.Now:yyyyMMdd}\{siteName}\{ActivitiesCasePhotoableType}");
            Directory.CreateDirectory($@"{prefix}\PDF\{DateTime.Now:yyyyMMdd}\{siteName}\{SpacePlaneFilePhotoableType}");
        }

        /// <summary>
        /// 下载原始图片
        /// </summary>
        /// <param name="siteName"></param>
        /// <param name="photoableType"></param>
        /// <param name="dtos"></param>
        private static List<KeyValuePair<string, string>> DownloadRawImages(string siteName, string photoableType, List<PhotoPdfDto> dtos)
        {
            var imgFileNames = new List<KeyValuePair<string, string>>();

            using (var wc = new WebClient())
            {
                foreach (var photoPdfDto in dtos)
                {
                    var path = photoPdfDto.Path;

                    if (path.IsNullOrEmpty()) continue;

                    var url = "http://storage.yunspace.com.cn/" + photoPdfDto.Path + "-790x526";
                    var newFileName = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
                    var newPath = $@"{siteName}\{photoableType}\";

                    try
                    {
                        var toSvaeImgFileName = $@"{_imageRawDirectory}\PDF\{DateTime.Now:yyyyMMdd}\{newPath}{newFileName}".Replace("-790x526", "");

                        wc.DownloadFile(url, toSvaeImgFileName);
                        imgFileNames.Add(new KeyValuePair<string, string>(toSvaeImgFileName, photoPdfDto.Tag));
                    }
                    catch (Exception e)
                    {
                        if (e.Message.Contains("404") || e.Message.Contains("400"))
                        {
                            continue;
                        }

                        throw;
                    }
                }
            }

            return imgFileNames;
        }

        /// <summary>
        /// 设置水印
        /// </summary>
        /// <param name="imgFileNames"></param>
        private static List<KeyValuePair<string, string>> SetWaterMark(List<KeyValuePair<string, string>> imgFileNames)
        {
            const string prefix = "watermark_";
            var waterMarkImgFileNames = new List<KeyValuePair<string, string>>();

            foreach (var fileName in imgFileNames)
            {
                var imgName = fileName.Key.Substring(fileName.Key.LastIndexOf(@"\", StringComparison.Ordinal) + 1);
                var prevPart = fileName.Key.Substring(0, fileName.Key.LastIndexOf(@"\", StringComparison.Ordinal) + 1);
                var waterMarkImgFileName = $"{prevPart}{prefix}{imgName}";

                WaterMarkHelper.AddImageSignText(fileName.Key, $"{prevPart}{prefix}{imgName}");
                waterMarkImgFileNames.Add(new KeyValuePair<string, string>(waterMarkImgFileName, fileName.Value));
            }

            return waterMarkImgFileNames;
        }

        /// <summary>
        /// 生成水印图片
        /// </summary>
        /// <param name="siteName"></param>
        /// <param name="photoableType"></param>
        /// <param name="dtos"></param>
        /// <returns></returns>
        private static List<KeyValuePair<string, string>> GenerateWaterMarkImgs(string siteName, string photoableType, List<PhotoPdfDto> dtos)
        {
            var rawImgs = DownloadRawImages(siteName, photoableType, dtos);
            return SetWaterMark(rawImgs);
        }

        /// <summary>
        /// 解析配套设施
        /// </summary>
        /// <param name="facilitiesStr"></param>
        /// <returns></returns>
        private string ResolveFacilities(string facilitiesStr)
        {
            if (facilitiesStr.IsNullOrEmpty())
            {
                return "";
            }

            var newStr = facilitiesStr.Replace("{", "").Replace("\"", "").Replace("n", "").Replace(":", "").Replace("}", "");
            var facilities = newStr.Split('|');

            var facilitiesItems = _itemsDetailApp.GetItemList("SiteSupportingFacilities");
            var needItems = facilities.Select(item => facilitiesItems.First(x => x.F_ItemCode == item).F_ItemName).ToList();

            return string.Join("，", needItems);
        }
    }
}
